TOP:=$(shell pwd)
ifneq ($(shell echo $$UID), 0)
export SUDO=sudo 
endif
ifeq ($(V), 1)
export VERBOSE=
else
export VERBOSE=@
endif
#
#This is makefile only for linux platform
#
UDK_HOST ?=Linux
UDK_ARCH ?=x86
CROSS_COMPILE:=
COMM_MODULE_AUTOINSTALL?=1

UDK_LIBDIR := $(TOP)/libs
UDK_BINDIR := $(TOP)/bin
UDK_OBJDIR := $(TOP)/.objs

UDKTESTSUITE_DIR := $(TOP)/test
CPPUNIT_DIR := $(UDKTESTSUITE_DIR)/cppunit/cppunit

CXXFLAGS += -fpic -fsigned-char -ffunction-sections -funwind-tables -fstack-protector \
	-fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 \
	-O2 \
	-Wa,--noexecstack -Wformat -Werror=format-security -fpermissive \
	-fexceptions -frtti
CXXFLAGS += -I$(TOP)/include -I$(TOP)/source/include \
	-I$(UDKTESTSUITE_DIR) -I$(CPPUNIT_DIR)/include \
	-I$(TOP)/source/stdsdk/include -I$(TOP)/source/pullsdk -I$(TOP)/jni \
	-I$(TOP)/source/pullsdk/include -I$(TOP)/source/plugin -I$(TOP)/thirdparty/tutk/include

ifdef DEBUG
CXXFLAGS += -g
endif


TUTK_P4P_STATIC_LIBRARY :=
TUTK_P4P_SHARED_LIBRARY :=

ifeq ($(strip $(COMM_MODULE_AUTOINSTALL)),1)
CXXFLAGS+=-DCOMM_MODULE_AUTOINSTALL

ifeq ($(strip $(UDK_ARCH)),mips)
CROSS_COMPILE:=mipsel-linux-
TUTK_P4P_STATIC_LIBRARY := $(TOP)/thirdparty/tutk/Linux/mips/libp4p.a
endif
ifeq ($(strip $(UDK_ARCH)),arm)
CROSS_COMPILE:=arm-linux-
TUTK_P4P_STATIC_LIBRARY := $(TOP)/thirdparty/tutk/Linux/arm/libp4p.a
endif
ifeq ($(strip $(UDK_ARCH)),x86)
#p4p library is 32bit arch
CXXFLAGS += -m32 
LDFLAGS += -m32
TUTK_P4P_STATIC_LIBRARY := $(TOP)/thirdparty/tutk/Linux/x86/libp4p.a
endif
else
ifeq ($(strip $(UDK_ARCH)),mips)
CROSS_COMPILE:=mipsel-linux-
endif
ifeq ($(strip $(UDK_ARCH)),arm)
CROSS_COMPILE:=arm-linux-
endif
ifeq ($(strip $(UDK_ARCH)),x86)
#p4p library is 32bit arch
CXXFLAGS += -m32 
LDFLAGS += -m32
endif
endif

#
#Sanity Checking
#
ASM	:=$(CROSS_COMPILE)as
LD	:=$(CROSS_COMPILE)ld
C	:=$(CROSS_COMPILE)gcc
CPP	:=$(CROSS_COMPILE)c++
CXX	:=$(CROSS_COMPILE)c++
AR	:=$(CROSS_COMPILE)ar
STRIP  	:=$(CROSS_COMPILE)strip
OBJCOPY	:=$(CROSS_COMPILE)objcopy
OBJDUMP	:=$(CROSS_COMPILE)objdump
RANLIB 	:=$(CROSS_COMPILE)ranlib


libudk_src := $(wildcard source/udk/*.cpp) \
	$(wildcard source/pd/linux/*.cpp) \
	$(wildcard source/common/*.cpp) \
	$(wildcard source/stdsdk/*.cpp) \
	$(wildcard source/pullsdk/*.cpp) 

default:all

#
#filter out commbt for linux platform
#

ifeq ($(strip $(COMM_MODULE_AUTOINSTALL)),1)
libudk_src += $(filter-out source/plugin/commbt.cpp,$(wildcard source/plugin/*.cpp))
build_comm_module:
clean_comm_module:
else
COMM_MODULES_PLUG_DIR:=source/plugin
COMM_MODULES_BUILT:=
COMM_MODULES_CLEAN:=
udk_os_dep:=$(patsubst %.cpp,$(UDK_OBJDIR)/modules/%.o,\
	$(wildcard source/common/*.cpp) $(wildcard source/pd/linux/*.cpp))
udk_os_dep_objdir := $(shell mkdir -p $(sort $(dir $(udk_os_dep))))
$(udk_os_dep):$(UDK_OBJDIR)/modules/%.o:%.cpp $(wildcard source/include/*.h) $(wildcard source/stdsdk/include/*.h) $(wildcard source/pullsdk/include/*.h)
	@echo " C++ : " $< " => " $(notdir $@)
	$(VERBOSE)$(CC) -c $< $(CXXFLAGS) -o $@
udk_os_dep:$(udk_os_dep)
define add-comm-module
$1_objs := $$(patsubst %.cpp,$$(UDK_OBJDIR)/%.o,$$(COMM_MODULES_PLUG_DIR)/$1.cpp ) 
$1_objdir := $$(shell mkdir -p $$(sort $$(dir $$($1_objs))))
$$($1_objs):$$(COMM_MODULES_PLUG_DIR)/$1.cpp
	@echo " C++ : " $$< " => " $$@ 
	$(VERBOSE)$(CC) -c $$< $(CXXFLAGS) -o $$@  
$1:$$($1_objs)
	$(VERBOSE)${AR} rcs $(UDK_LIBDIR)/lib$1.a $$($1_obj) $(udk_os_dep)
	$(VERBOSE)${CC} $(LDFLAGS) --shared -o $(UDK_LIBDIR)/lib$1.so $$($1_obj) $(udk_os_dep)
$1_clean:
	-$(VERBOSE)rm -rf $(UDK_LIBDIR)/lib$1.a
	-$(VERBOSE)rm -rf $(UDK_LIBDIR)/lib$1.so
	-$(VERBOSE)rm -rf $$($1_objs)
COMM_MODULES_BUILT +=$(1)
COMM_MODULES_CLEAN +=$(1)_clean
endef
$(foreach module,$(filter-out commbt,$(basename $(notdir $(wildcard $(COMM_MODULES_PLUG_DIR)/*.cpp)))),$(eval $(call add-comm-module,$(module))))
build_comm_module:udk-dependency udk_os_dep $(COMM_MODULES_BUILT)
clean_comm_module:$(COMM_MODULES_CLEAN)
endif
	
libudk_objs := $(patsubst %.cpp, $(UDK_OBJDIR)/%.o, $(libudk_src))
libudk_objdir := $(shell mkdir -p $(sort $(dir $(libudk_objs))))
libudk := libudk.so

udktestsuite_src := $(wildcard test/*.cpp) 
udktestsuite_objs := $(patsubst %.cpp, $(UDK_OBJDIR)/%.o, $(udktestsuite_src))
udktestsuite_objdir := $(shell mkdir -p $(sort $(dir $(udktestsuite_objs))))


SUFFIXES += .d
.PHONY: $(libudk) install-host install-target clean clean-local \
	uninstall-host uninstall-target distclean
.IGNORE:install-host


#
#default entry
#
all: udk install udktest completed

udk:udk-dependency $(libudk) build_comm_module udkdoc
udk-dependency:
	-@mkdir -p $(UDK_LIBDIR)
	-@mkdir -p $(UDK_OBJDIR)

$(libudk_objs):$(UDK_OBJDIR)/%.o:%.cpp $(wildcard include/*.h) $(wildcard source/include/*.h) $(wildcard source/stdsdk/include/*.h) $(wildcard source/pullsdk/include/*.h)
	@echo " C++ : " $< " => " $(notdir $@)
	$(VERBOSE)$(CC) -c $< $(CXXFLAGS) -o $@

$(libudk): $(libudk_objs)
	$(VERBOSE)${AR} -r $(UDK_LIBDIR)/libudk.a ${libudk_objs} $(TUTK_P4P_STATIC_LIBRARY) 
	$(VERBOSE)${CC} $(LDFLAGS) --shared -o $(UDK_LIBDIR)/$@ ${libudk_objs} $(TUTK_P4P_STATIC_LIBRARY)
udkdoc:	
	make -C doc

udkdoc-clean:
	make -C doc clean

udktest:udktest-dependency udktestsuite

udktest-dependency:
	-mkdir -p bin

$(udktestsuite_objs):$(UDK_OBJDIR)/%.o:%.cpp $(wildcard test/*.h) $(wildcard include/*.h) $(wildcard source/include/*.h) $(wildcard source/stdsdk/include/*.h) $(wildcard source/pullsdk/include/*.h)
	@echo " C++ : " $< " => " $(notdir $@)
	$(VERBOSE)$(CC) -c $< $(CXXFLAGS) -o $@

udktestsuite:$(libudk) cppunit $(udktestsuite_objs)
	${CC} $(LDFLAGS) -L$(UDK_LIBDIR) -rdynamic $(udktestsuite_objs) -o $(UDK_BINDIR)/$@ \
	-ludk -lcppunit -lstdc++ -lpthread -ldl
	
cppunit:
	@echo "############################################";
	@echo "#           building cppunit lib...           #";
	@echo "############################################";
	@(if [ ! -f $(TOP)/test/cppunit/cppunit/Makefile ];then \
	cd $(TOP)/test/cppunit/cppunit;\
	./autogen.sh;\
	./configure prefix=/usr CXXFLAGS=-m32 LDFALGS=-m32;\
	make -C $(TOP)/test/cppunit/cppunit;\
	$(SUDO) make -C $(TOP)/test/cppunit/cppunit install; \
	fi;\
	cd $(TOP);\
	)

cppunit_clean:
	$(VERBOSE)(if [ -f $(CPPUNIT_DIR)/Makefile ];then \
	 make -C $(CPPUNIT_DIR) distclean; \
	fi;\
	)

install:install-host install-target

install-host:
	$(SUDO) install -m 664 $(UDK_LIBDIR)/libudk.a /usr/lib
	$(SUDO) install -m 664 $(UDK_LIBDIR)/libudk.so /usr/lib 
install-target:

uninstall:clean


clean: udkdoc-clean cppunit_clean clean-local uninstall-host uninstall-target clean-done


distclean:clean
	-rm -rf $(CPPUNIT_DIR)/Makefile

clean-local:clean_comm_module
	-$(VERBOSE)find $(TOP) -name '*.o' -exec rm -f {} ';'
	-$(VERBOSE)find $(TOP) -name '*~' -exec rm -f {} ';'
	-$(VERBOSE)find $(TOP) -name '*.bak' -exec rm -f {} ';'
	-$(VERBOSE)rm -rf $(UDK_LIBDIR)
	-$(VERBOSE)rm -rf $(UDK_BINDIR)
	-$(VERBOSE)rm -rf $(UDK_OBJDIR)

uninstall-host:
	
uninstall-target:

completed:
	@echo "build completed!"

clean-done:	
	@echo "clean completed!"
	
